﻿using System;
using System.Text;
using ParserGenerator.GrammarConstruction;

namespace ParserGenerator.ParserConstruction
{
    [Serializable]
    public sealed class ParserAutomatonItem
    {
        public int Number { get; internal set; }
        public ParserAutomatonItemTable Table { get; internal set; }
        public GrammarProduction Production { get; internal set; }
        public int DotPosition { get; internal set; }
        public bool IsRead => DotPosition < Production.Length;
        public bool IsReduce => DotPosition == Production.Length;
        public bool IsAccept => IsReduce && Production.IsAccept;
        public bool HasSymbol => IsRead;
        public GrammarSymbol Symbol => Production.Symbols[DotPosition];
        public bool IsShift => HasSymbol && Symbol.IsTerminal;
        public bool IsGoto => HasSymbol && Symbol.IsNonterminal;
        public bool SeesLookaheadSet => Table.ItemsSeeLookaheadSet.Contains(this);
        public bool HasPredecessor => DotPosition > 0;
        public bool HasSuccessor => DotPosition < Production.Length;
        public ParserAutomatonItem Predecessor => HasPredecessor ? Table[Number - 1] : null;
        public ParserAutomatonItem Successor => HasSuccessor ? Table[Number + 1] : null;

        internal ParserAutomatonItem()
        {
        }

        public sealed override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(Production.Owner.Name);
            sb.Append(" ->");
            for (int i = 0; i <= Production.Length; i++)
            {
                if (i == DotPosition)
                    sb.Append(" .");
                if (i < Production.Length)
                    sb.AppendFormat(" {0}", Production.Symbols[i].Name);
            }
            return sb.ToString();
        }
    }
}
